import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:im_flutter_sdk/im_flutter_sdk.dart';
import 'package:qunaimedical/im/chat/chat_page.dart';
import 'package:qunaimedical/utils/auth_util.dart';
import 'package:qunaimedical/utils/event_bus_manager.dart';
import 'package:qunaimedical/utils/log_util.dart';
import 'package:qunaimedical/utils/navigator_util.dart';
import 'package:qunaimedical/utils/sp_util.dart';
import 'package:qunaimedical/values/urls.dart';
import 'package:webview_flutter/webview_flutter.dart';

// 2022.11.23 mod lyy file upload
import 'package:file_picker/file_picker.dart';//导入filepicker
import 'package:dio/dio.dart';//导入dio

enum WebType {
  terms,
}

class WebPage extends StatefulWidget {
  final String? url, title;
  final WebType? type;
  final WebViewCookie? webViewCookie;

  const WebPage({Key? key, this.url, this.title, this.type, this.webViewCookie})
      : super(key: key);

  @override
  _WebPageState createState() => _WebPageState();
}

class _WebPageState extends State<WebPage> {
  final String _tag = '_WebPageState';

  String _termsPath = 'assets/html/terms.html';

  WebViewController? _controller;
  late StreamSubscription _eventSubscription;

  String? _title;

  @override
  void initState() {
    super.initState();
    setState(() {
      _title = widget.title;
    });
    _eventSubscription = eventBus.on<EventBusMessage>().listen((event) {
      if (event == EventBusMessage.refreshWebpage) {
        String? newUrl = wrapUrl(widget.url);
        if (newUrl != null) {
          _controller?.loadUrl(newUrl);
        }
      }
    });
  }

  @override
  void dispose() {
    super.dispose();
    _eventSubscription.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        if (_controller != null) {
          bool canGoBack = await _controller!.canGoBack();
          if (canGoBack) {
            _controller!.goBack();
            return Future.value(false);
          }
        }
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(_title ?? ""),
          elevation: 0,
        ),
        body: WebView(
          initialUrl: wrapUrl(widget.url),
          javascriptMode: JavascriptMode.unrestricted,
          zoomEnabled: false,
          initialCookies:
              widget.webViewCookie == null ? [] : [widget.webViewCookie!],
          onWebViewCreated: (WebViewController controller) async {
            _controller = controller;
            if (widget.type != null) {
              if (widget.type == WebType.terms) {
                _loadLocalHTML(controller, _termsPath);
              }
            }
          },
          onPageFinished: (url) async {
            String? title = await _controller?.getTitle();
            if (title != null) {
              setState(() {
                _title = title;
              });
            }
          },
          javascriptChannels: Set.from([
            JavascriptChannel(
              name: 'doctorDetail',
              onMessageReceived: (JavascriptMessage message) async {
                Log.d(_tag, "data from doctorDetailPage: ${message.message}");
                Map<String, dynamic> data = json.decode(message.message);
                
				// 聊天页面
                  if( data["toName"] !=null) {
                    EMConversation? conv = await EMClient.getInstance
                      .chatManager
                      .getConversation(data["id"]);
                    conv?.setExt({"id": data["id"], "name": data["toName"]});
                    if (conv != null) {
                      pushTo(context, ChatPage(conv));
                    }
                  }

                  // 2022.11.23 mod lyy file upload
                  if(  data["appointmentId"] != null ){
                    _flutterUploadFile(data);
                  }
              },
            ),
            JavascriptChannel(
              name: 'autoLogin',
              onMessageReceived: (JavascriptMessage message) async {
                Log.d(_tag, "data from autoLogin: ${message.message}");
                Map<String, dynamic> data = json.decode(message.message);
                var value = data["state"];
                if (value == "meet") {
                  eventBus.fire(EventBusMessage.jump2ConsultationCenter);
                }
                if (value == "me") {
                  eventBus.fire(EventBusMessage.jump2Me);
                }
                Navigator.pop(context);
              },
            ),
          ]),
        ),
      ),
    );
  }

  // 2022.11.23 mod lyy file upload
  void _flutterUploadFile(Map<String, dynamic> data) async
  {
        Log.d(_tag, "pick file.  param >> meet id: ${ data["appointmentId"]}");
        String? path;
        String pathUse="";
        FilePickerResult?  result  = await FilePicker.platform.pickFiles();

        if (result != null) {
          PlatformFile file = result.files.first;
          path = file.path;                  //取数据，有name，path，size等等，这就取个文件地址

          //刷新界面显示数据,否则下面的text不更新
          //setState(() {      });
        } else {
          // User canceled the picker
        }
    //                  版权声明：本文为CSDN博主「咸鱼得翻身不然就糊了」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
    //                  原文链接：https://blog.csdn.net/weixin_45324843/article/details/122882434
        //获取路径
    //                    setState(() {
    //                      this._file = fileUrl;
    //                    });

        pathUse= (path==null)?"":path;
        Log.d(_tag, "pick file.  step >> path: ${pathUse }");
        Log.d(_tag, "pick file.  step >> js data: ${ data["id"] }");
        Log.d(_tag, "pick file.  step >> login: ${ SPUtil.getUserName() },${ SPUtil.getPassword() }");

        String fileNameShow = pathUse.substring(pathUse.lastIndexOf("/") + 1, pathUse.length);  // 文件名this._fileNameShow = fileNameShow;

        String fname = fileNameShow.substring(0, fileNameShow.lastIndexOf("."));
        String ftype = fileNameShow.substring(  fileNameShow.lastIndexOf("."), fileNameShow.length ) ;

        // 上传时也需要登录状态保持
        FormData formData = FormData.fromMap({
          // 2022.11.23 auto login 上传时的登录状态保持
          "autoTest":  "autoLogin",
          "userName":  SPUtil.getUserName(),
          "password":  SPUtil.getPassword(),

          "user_id":  data["id"],
          "appointment_id": data["appointmentId"],
          "report_id": "1",
          "report_time": "09:00:00",
          "clientfilename": fname,
          "clientfiletype":  ftype,
          "report_file":  await MultipartFile.fromFile(pathUse, filename: fileNameShow),
        });

        // http://gaiwo.belovedlive.com:8098/
        Log.d(_tag, "build form.  step >> form data: ${fname }--${ ftype }");

        //  当带有data["fileStore"] == "tencent" 时，传到腾讯云
        String uploadTarget="${ Urls.BASE_URL}/boke/meetfiles_addfile.do";
        if( data["fileStore"] == "tencent" ) {
          uploadTarget =   "${ Urls.BASE_URL}/bokehall/files/upload";
        }
        // bokehall/files/upload 报302-->  Unhandled Exception: DioError [DioErrorType.response]: Http status error [302]

        var response =await Dio().post(uploadTarget, data: formData);
        Log.d(_tag, "web req.  step >> get resp");
        Log.d(_tag, response);
        print(response);

        if (response.statusCode == 200) {
          print('response上传之后展示');
          print(response);
           _controller?.runJavascript("linkFlutter()"); // 上传成功之后调用的JS方法,类似刷新吧
        }

        Log.d(_tag, "upload file. finish.");

        //_controller?.reload(); // 刷新当前webview
  }
  
  void _loadLocalHTML(WebViewController controller, String path) async {
    String fileHtmlContents = await rootBundle.loadString(path);
    controller.loadUrl(Uri.dataFromString(fileHtmlContents,
            mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
        .toString());
  }

  String? wrapUrl(String? url) {
    if (url != null && url.contains(Urls.DOMAIN)) {
      url += "${url.contains("?") ? "&" : "?"}from=app";
      if (AuthUtil.isLogin()) {
        url +=
            "&autoTest=autoLogin&userName=${SPUtil.getUserName()}&password=${SPUtil.getPassword()}";
      }
      Log.d(_tag, "open url: $url");
    }
    return url;
  }
}
